﻿/**
* @authors Duong NGUYEN <darl2ng@gmail.com>, Anh NGO <ngocanh.ngo@gmail.com>
* @version 0.9
* Copyright 2010
* 
* The MIT License
* Copyright (c) 2010 <Duong NGUYEN <darl2ng@gmail.com>, Anh NGO <ngocanh.ngo@gmail.com>
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package {
	
	import c_ResObject;
	import com.ng.utils.c_XML;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	import flash.text.TextField;
	import XML;

	public class c_ResEditor extends Sprite {
		
		public static var OBJECT_SELECT:String = "OBJECT_SELECT";
		
		private var __ClassesId: Array = null;
		private var __currentSelect: c_ResObject = null;		
		private var __currentFrame: c_ResObject = null;
		private var __colorTransform: ColorTransform ;
		
		private var __ResHelper:c_ResHelper2;
		
		private var __GridInterval:int = 0;
		
		static private var __OverrideInstance:c_ResEditor;
		
		static public function GetInstance():c_ResEditor {
			if(__OverrideInstance == null)
				__OverrideInstance = new c_ResEditor();
			return __OverrideInstance;
		}		
		
		public function Init(p_ResHelper:c_ResHelper2):c_ResEditor {
			__ResHelper = p_ResHelper;
			__ClassesId = null;
			__colorTransform = new ColorTransform();
			__colorTransform.redOffset = 155;
			__colorTransform.greenMultiplier = 0.5;
			
			if ("@gridInterval" in __ResHelper.xml.Presentation) { //correct way to check availability of an attribute
				__GridInterval = __ResHelper.xml.Presentation.attribute("gridInterval");
				trace("GridInterval:"+__GridInterval);
			}
			
			return this;
		}		
		public function get xml():XML {
			return __ResHelper.xml;
		}
		public function get currentSelect():c_ResObject {
			return __currentSelect;
		}
		public function get classId():Array {
			if(__ClassesId == null){
				__ClassesId = new Array();
				for each (var item:XML in __ResHelper.xml.Loadings.Swfs.Swf.(@loading == "auto").Class) {
					if (item.attribute("isFont")!="true") {
						__ClassesId.push(item.attribute("id"));
					}
				}
			}
			return __ClassesId;
		}
		public function getAllFrameId():Array {
			var ar: Array = new Array();			
			for each (var frame:XML in __ResHelper.xml.Presentation.Frame) {
				ar.push(frame.@id.toString());
			}
			return ar;
		}		
		public  function getFrameById(frame_id:String):c_ResObject{
			var fr:c_ResObject=__ResHelper.getResObjectById(frame_id);
			__currentFrame = fr;
			SetEventListener(__currentFrame);
			return fr;
		}
		public function CleanUp():void {
			if (__currentFrame !=null) {
				RemoveEventListener(__currentFrame);
			}
		}
		private function RemoveEventListener(fr:c_ResObject):void {
			for (var i:int = 0; i < fr.numChildren; i++ ) {				
				var sp:Object = fr.getChildAt(i);
				if (sp is c_ResObject) {
					sp.removeEventListener(MouseEvent.CLICK, mouseClickHandler);
					sp.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
					sp.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
					RemoveEventListener(sp);
				}
			}
		}
		private function SetEventListener(fr:c_ResObject):void {
			for (var i:int = 0; i < fr.numChildren; i++ ) {
				var sp:Object = fr.getChildAt(i);
				if (sp is c_ResObject) {
					sp.addEventListener(MouseEvent.CLICK, mouseClickHandler);
					sp.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
					sp.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
					SetEventListener(sp);
				} else if (sp is MovieClip) {					
					//fix the static font just in case					
					for (var i:int = 0; i < sp.numChildren;  i++) {
						var o:Object = sp.getChildAt(i);
						if (o is TextField) {					
							var te:TextField = (o as TextField);
							te.mouseEnabled = false;						
							te.embedFonts = true;			
						}
					}
				}
			}
		}
		public function UpdateXML(item:XML, e:c_ResObject) {
			var i:Number;
			for (i = 0; i < e.changedProperties.length; i++) {
				item.@[e.changedProperties[i]] = e.Content[e.changedProperties[i]];
				//trace(e.changedProperties[i] +" : "+e[e.changedProperties[i]]);
			}
			if (e.Content.visible == false) {
				item.@visible = false;
			} else {
				item.@visible = true;
			}
			
			//do all the update with the content, except for the position
			item.@x = e.x;
			item.@y = e.y;			
		}		
		public function SaveXML(filename:String) {
			c_XML.saveXML(__ResHelper.xml, filename);
		}		
		public function deleteXMLItem(item:XML) {
			var p:XML = item.parent();
			if(p != null){
				delete p.elements()[item.childIndex()];
			}
		}
		//-----------------------------------------------------------------------------------
		public function bringCurrentToBack() {
			if (__currentSelect != null) {
				var p: XML = __currentSelect.xml.parent();
				
				if (p != null) {
					var tmp:XML = __currentSelect.xml.copy();
					p.prependChild(tmp);
					deleteXMLItem(__currentSelect.xml);
					__currentSelect.xml = tmp;
				}
				if (__currentSelect.parent != null) {
					__currentSelect.parent.setChildIndex(__currentSelect, 0);
				}
				
			}
		}
		//-----------------------------------------------------------------------------------
		public function bringCurrentToFront() {
			if (__currentSelect != null) {
				var p: XML = __currentSelect.xml.parent();
				
				if (p != null) {
					var tmp:XML = __currentSelect.xml.copy();
					p.appendChild(tmp);
					deleteXMLItem(__currentSelect.xml);
					__currentSelect.xml = tmp;
				}				
				if (__currentSelect.parent != null) {
					__currentSelect.parent.setChildIndex(__currentSelect, __currentSelect.parent.numChildren-1);
				}				
			}
		}
		//-----------------------------------------------------------------------------------
		public function deleteCurrentSelect() {
			if (__currentSelect != null) {
				deleteXMLItem(__currentSelect.xml);
				if (__currentSelect.parent != null) {
					__currentSelect.parent.removeChild(__currentSelect);
				}
				__currentSelect = null;
			}
		}
		//-----------------------------------------------------------------------------------
		public function newItem(className: String):void {
			var item:c_Item;
			if (__ResHelper != null) {
				var f:c_ResObject;
				//fame and element selected: create a child of the element
				if (__currentSelect != null) {
					f = __currentSelect;
				//no element selected, create a child of the selected frame 
				}else if (__currentFrame != null){
					f = __currentFrame;
				}
				if (f!=null && f.xml !=null) {
					item = new c_Item(f, className);					
					f.xml.appendChild(item.xml);
					__ResHelper.addItem(item,f);
				}
			} else {
				throw new Error("c_ResEditor::newItem[ResHelper not loaded]");
			}
		}
		
		//-----------------------------------------------------------------------------------
		private function mouseDownHandler(event:MouseEvent):void {
			var ro:c_ResObject = event.target as c_ResObject;
			ro.startDrag();
		}

		private function mouseUpHandler(event:MouseEvent):void {
			var ro:c_ResObject = event.target as c_ResObject;
			ro.stopDrag();
			adjust(ro);
			UpdateXML(ro.xml,ro);
		}
		
		private function mouseClickHandler(event:MouseEvent):void {
			var ro:c_ResObject = event.target as c_ResObject;
			select(ro);
		}
		private function select(mc: c_ResObject) {
			unSelect();
			__currentSelect = mc;
			mc.oldtransform = mc.transform.colorTransform;
			mc.transform.colorTransform = __colorTransform;			
			if (mc.oldalpha != null) {			
				mc.alpha = mc.oldalpha;
			}
			dispatchEvent(new Event(OBJECT_SELECT));
		}
		public function unSelect() {
			if (__currentSelect != null) {
				__currentSelect.oldalpha = __currentSelect.alpha;
				__currentSelect.transform.colorTransform = __currentSelect.oldtransform;
				 __currentSelect.alpha = __currentSelect.oldalpha;
				__currentSelect = null;
			}
		}
		private function adjust(ro:c_ResObject):void {
			var mod:int;
			mod = ro.x % __GridInterval;
			ro.x -= mod;			
			if (mod>__GridInterval/2) {				
				ro.x += __GridInterval;
			}
			mod = ro.y % __GridInterval;
			ro.y -= mod;
			if (mod>__GridInterval/2) {				
				ro.y += __GridInterval;
			}
		}
	}
}